package com.eastfair.builder.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.builder.dao.ExhibitorMapper;
import com.eastfair.builder.dto.ActorInfoDTO;
import com.eastfair.builder.dto.ExhibitorDTO;
import com.eastfair.builder.entity.Exhibitor;
import com.eastfair.builder.entity.ReportSpace;
import com.eastfair.builder.enumeration.*;
import com.eastfair.builder.exceptioncode.BuilderExceptionCode;
import com.eastfair.builder.service.*;
import com.eastfair.builder.vo.ActorInfo;
import com.eastfair.builder.vo.ActorInfoBoot;
import com.eastfair.builder.vo.ActorPersonJoin;
import com.eastfair.builder.vo.ExhibitorVO;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.exception.code.ExceptionCode;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.database.mybatis.typehandler.TypeHandlerUtil;
import com.eastfair.home.enumeration.BuilderRepairReportRepairStatusEnum;
import com.eastfair.home.vo.BuilderRepairReportVO;
import com.eastfair.venuebooking.api.SpaceFeign;
import com.eastfair.venuebooking.vo.SpaceVO;
import com.eastfair.venueservice.dto.ExhibitionServiceProviderDTO;
import com.eastfair.venueservice.dto.ServiceProviderSpaceQuery;
import com.eastfair.venueservice.enumeration.*;
import com.eastfair.venueservice.vo.BondManageVO;
import com.eastfair.venueservice.vo.ServiceOrderVO;
import com.eastfair.venueservice.vo.ServiceProviderVO;
import com.eastfair.venueservice.vo.WorkOvertimeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 展商
 * </p>
 *
 * @author dq
 * @date 2022-08-06
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ExhibitorServiceImpl extends SuperServiceImpl<ExhibitorMapper, Exhibitor> implements ExhibitorService {

    @Resource
    private BuilderExhibitionCompanyService builderExhibitionCompanyService;

    @Resource
    private BuilderServiceProviderService builderServiceProviderService;

    @Resource
    private BuilderExhibitionServiceProviderService builderExhibitionServiceProviderService;

    @Resource
    private ReportSpaceService reportSpaceService;

    @Resource
    private MeetActorService meetActorService;

    @Resource
    private BuilderHomeServiceOrderService builderHomeServiceOrderService;

    @Resource
    private BuilderHomeBondManageService builderHomeBondManageService;

    @Resource
    private BuilderBuilderRepairReportService builderBuilderRepairReportService;

    @Resource
    private BuilderWorkOvertimeService builderWorkOvertimeService;

    @Resource
    private SpaceFeign spaceFeign;

    @Resource
    private ExhibitorMapper exhibitorMapper;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<Exhibitor> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(Exhibitor model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        if (model.getSiteType() == null) {
            throw BizException.wrap(ExceptionCode.BASE_VALID_PARAM.getCode(), "展位类型不能为空");
        }
        if (model.getSiteStatus() == null) {
            if (ExhibitorSiteTypeEnum.SPECIAL.eq(model.getSiteType())) {
                model.setSiteStatus(ExhibitorSiteStatusEnum.UNREPORT);
            } else if (ExhibitorSiteTypeEnum.STANDARD.eq(model.getSiteType())) {
                model.setSiteStatus(ExhibitorSiteStatusEnum.SHOW);
            }
        }
        if (model.getEarnestMoneyPayStatus() == null) {
            if (ExhibitorSiteTypeEnum.SPECIAL.eq(model.getSiteType())) {
                model.setEarnestMoneyPayStatus(ExhibitorEarnestMoneyPayStatusEnum.NOT_PAY);
            } else if (ExhibitorSiteTypeEnum.STANDARD.eq(model.getSiteType())) {
                model.setEarnestMoneyPayStatus(ExhibitorEarnestMoneyPayStatusEnum.NOT_NEED_PAY);
            }
        }
        if (model.getShouldEarnestMoney() == null) {
            model.setShouldEarnestMoney(BigDecimal.ZERO);
        }
        if (model.getActualEarnestMoney() == null) {
            model.setActualEarnestMoney(BigDecimal.ZERO);
        }
        if (model.getRemainEarnestMoney() == null) {
            model.setRemainEarnestMoney(BigDecimal.ZERO);
        }
        return R.successDef();
    }

    @Override
    public Page<ExhibitorVO> listExhibitorVOs(PageParams<ExhibitorDTO> pageParams) {
        log.info("listExhibitorVOs - 查询展商列表VO, pageParams={}", pageParams);
        ExhibitorDTO model = pageParams.getModel();
        Page<Exhibitor> page = listExhibitors(pageParams);
        Page<ExhibitorVO> voPage = new Page<>();
        BeanUtil.copyProperties(page, voPage);
        List<Exhibitor> list = page.getRecords();
        if (list == null || list.isEmpty()) {
            return voPage;
        }
        List<String> spaceCodeList = new ArrayList<>();
        List<Long> exhibitorIds = new ArrayList<>();
        list.forEach(exhibitor -> {
            exhibitorIds.add(exhibitor.getId());
            spaceCodeList.add(exhibitor.getSpaceCode());
        });
        // 查询展商报馆信息
        Map<Long, ReportSpace> reportSpaceStatusMap = reportSpaceService.getMapByExhibitorIds(exhibitorIds);
        // 查询负责展商的主场
        Map<String, List<ServiceProviderVO>> serviceProviderMap = builderServiceProviderService
                .getServiceProviderVOMapByExhibitionId(model.getExhibitionManageId(), spaceCodeList, ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode());
        // 查询管理费支付状态
        Map<Long, String> manageOrderPayStatusMap = builderHomeServiceOrderService.getManageOrderPayStatus(exhibitorIds);
        // 查询保证金支付状态
        Map<Long, String> bondPayStatusMap = builderHomeBondManageService.getBondPayStatus(exhibitorIds);
        //  转换数据
        List<ExhibitorVO> voList = list
                .stream()
                .map(exhibitor -> {
                    ExhibitorVO exhibitorVO = BeanUtil.toBean(exhibitor, ExhibitorVO.class);
                    // 添加展位报馆状态
                    setReportSpaceStatus(exhibitorVO, reportSpaceStatusMap);
                    // 添加负责的主场
                    setHome(exhibitorVO, serviceProviderMap);
                    // 管理费缴纳状态
                    setManagePayStatus(exhibitorVO, manageOrderPayStatusMap);
                    // 保证金缴纳状态
                    setBondPayStatus(exhibitorVO, bondPayStatusMap);
                    return exhibitorVO;
                })
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public Page<ExhibitorVO> listNotReportSpaceExhibitorVOs(PageParams<ExhibitorDTO> pageParams) {
        log.info("listNotReportSpaceExhibitorVOs - 分页查询未报馆的展位列表, pageParams={}", pageParams);
        Page<Exhibitor> pageParam = pageParams.buildPage();
        ExhibitorDTO model = pageParams.getModel();
        QueryWrapper<Exhibitor> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("e.is_deleted", BusinessConstant.DELETE_NO)
                .eq("e.is_enabled", BusinessConstant.YES)
                .eq("e.site_type", ExhibitorSiteTypeEnum.SPECIAL.getCode())
                .isNull(model.getId() == null, "rs.id")
                .eq(model.getId() != null, "e.id", model.getId())
                .eq(model.getExhibitionManageId() != null, "e.exhibition_manage_id", model.getExhibitionManageId())
                .eq(model.getBuilderId() != null, "e.builder_id", model.getBuilderId())
                .like(StrUtil.isNotBlank(model.getSpaceName()), "e.space_name", model.getSpaceName())
                .like(StrUtil.isNotBlank(model.getSiteName()), "e.site_name", model.getSiteName())
        ;
        Page<ExhibitorVO> voPage = exhibitorMapper.listNotReportSpaceExhibitorVOs(pageParam, queryWrapper);
        List<ExhibitorVO> voList = voPage.getRecords();
        if (voList == null || voList.isEmpty()) {
            return voPage;
        }
        for (ExhibitorVO exhibitorVO : voList) {
            decryptContactMobile(exhibitorVO);
            decryptExhibitorContactsTel(exhibitorVO);
            decryptPrincipalPhone(exhibitorVO);
        }
        return voPage;
    }

    @Override
    public List<ExhibitorVO> listByInviteCode(String inviteCode, Long exhibitionId) {
        log.info("listByInviteCode - 展商邀请码获取展商列表, inviteCode={}, exhibitionId={}", inviteCode, exhibitionId);
        ActorInfoDTO actorInfoQuery = new ActorInfoDTO();
        actorInfoQuery.setExhSourceID(exhibitionId + "");
        actorInfoQuery.setAtrExhBuildInviteCode(inviteCode);
        List<ActorInfo> actorInfoList;
        try {
            actorInfoList = meetActorService.getActorInfoByBuildInviteCode(actorInfoQuery);
        } catch (Exception e) {
            log.error("调用展商邀请码接口失败", e);
            throw BizException.wrap(1001, "展商邀请码有误，请重新输入");
        }
        if (actorInfoList == null || actorInfoList.isEmpty()) {
            return Collections.emptyList();
        }
        return toExhibitorList(actorInfoList);
    }

    @Override
    public List<Exhibitor> listByInviteCode(String inviteCode) {
        log.info("listByInviteCode - 展商邀请码查询展商列表, inviteCode={}", inviteCode);
        ExhibitorDTO query = new ExhibitorDTO();
        query.setInviteCode(inviteCode);
        return listExhibitors(query);
    }

    @Override
    public Page<Exhibitor> listExhibitors(PageParams<ExhibitorDTO> pageParams) {
        log.info("listExhibitors - 查询展商列表, pageParams={}", pageParams);
        Page<Exhibitor> page = pageParams.buildPage();
        ExhibitorDTO query = pageParams.getModel();
        QueryWrapper<Exhibitor> queryWrapper = createExhibitorQueryWrapper(query);
        return page(page, queryWrapper);
    }

    @Override
    public List<ExhibitorVO> listExhibitorVOs(ExhibitorDTO exhibitorDTO) {
        List<Exhibitor> exhibitors = listExhibitors(exhibitorDTO);
        if (exhibitors == null || exhibitors.isEmpty()) {
            return Collections.emptyList();
        }
        List<Long> ExhibitorIds = exhibitors
                .stream()
                .map(SuperEntity::getId)
                .collect(Collectors.toList());
        // 查询管理费缴纳状态
        Map<Long, String> manageOrderPayStatusMap = builderHomeServiceOrderService.getManageOrderPayStatus(ExhibitorIds);
        // 查询保证金缴纳状态
        Map<Long, String> bondPayStatusMap = builderHomeBondManageService.getBondPayStatus(ExhibitorIds);
        return exhibitors
                .stream()
                .map(exhibitor -> {
                    ExhibitorVO exhibitorVO = BeanUtil.toBean(exhibitor, ExhibitorVO.class);
                    // 管理费缴纳状态
                    setManagePayStatus(exhibitorVO, manageOrderPayStatusMap);
                    // 保证金缴纳状态
                    setBondPayStatus(exhibitorVO, bondPayStatusMap);
                    return exhibitorVO;
                })
                .filter(exhibitorVO -> {
                    if (StrUtil.isNotBlank(exhibitorDTO.getBondPayStatus()) && ServiceOrderPayStatusEnum.HAS_PAY.eq(exhibitorDTO.getBondPayStatus())) {
                        return StrUtil.isNotBlank(exhibitorVO.getBondPayStatus()) && ServiceOrderPayStatusEnum.HAS_PAY.eq(exhibitorVO.getBondPayStatus());
                    }
                    return true;
                })
                .filter(exhibitorVO -> {
                    if (StrUtil.isNotBlank(exhibitorDTO.getManageOrderPayStatus()) && ServiceOrderPayStatusEnum.HAS_PAY.eq(exhibitorDTO.getManageOrderPayStatus())) {
                        return StrUtil.isNotBlank(exhibitorVO.getManageOrderPayStatus()) && ServiceOrderPayStatusEnum.HAS_PAY.eq(exhibitorVO.getManageOrderPayStatus());
                    }
                    return true;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<Exhibitor> listExhibitors(ExhibitorDTO exhibitorDTO) {
        QueryWrapper<Exhibitor> queryWrapper = createExhibitorQueryWrapper(exhibitorDTO);
        return list(queryWrapper);
    }

    @Override
    public Page<ExhibitorVO> queryServiceProviderSite(PageParams<ExhibitorDTO> query) throws Exception {
        log.info("queryServiceProviderSite - 通过展会，主场，展厅查询展位, query={}", query);
        Page<Exhibitor> page = query.buildPage();
        ExhibitorDTO model = query.getModel();
        QueryWrapper<Exhibitor> wrapper = createQueryWrapperForServiceProviderSite(model);
        Page<ExhibitorVO> voPage = exhibitorMapper.listServiceProviderSite(page, wrapper);
        List<ExhibitorVO> voList = voPage.getRecords();
        if (voList == null || voList.isEmpty()) {
            return voPage;
        }
        List<String> spaceCodeList = new ArrayList<>();
        List<Long> exhibitorIds = new ArrayList<>();
        voList.forEach(exhibitor -> {
            exhibitorIds.add(exhibitor.getId());
            spaceCodeList.add(exhibitor.getSpaceCode());
        });
        if (model.getExhibitionManageId() == null || spaceCodeList.isEmpty()) {
            return voPage;
        }
        // 查询负责展位的主场
        Map<String, List<ServiceProviderVO>> serviceProviderMap
                = builderServiceProviderService.getServiceProviderVOMapByExhibitionId(model.getExhibitionManageId(), spaceCodeList, ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode());
        // 查询管理费缴纳状态
        Map<Long, String> manageOrderPayStatusMap = builderHomeServiceOrderService.getManageOrderPayStatus(exhibitorIds);
        // 查询保证金缴纳状态
        Map<Long, String> bondPayStatusMap = builderHomeBondManageService.getBondPayStatus(exhibitorIds);
        for (ExhibitorVO exhibitorVO : voList) {
            decryptContactMobile(exhibitorVO);
            decryptExhibitorContactsTel(exhibitorVO);
            decryptPrincipalPhone(exhibitorVO);
            // 管理费缴纳状态
            setManagePayStatus(exhibitorVO, manageOrderPayStatusMap);
            // 保证金缴纳状态
            setBondPayStatus(exhibitorVO, bondPayStatusMap);
            // 负责的主场
            setHome(exhibitorVO, serviceProviderMap);
        }
        return voPage;
    }

    @Override
    public List<ExhibitorVO> queryAllServiceProviderSite(ServiceProviderSpaceQuery query) {
        return ConvertUtil.convertList(list(new QueryWrapper<Exhibitor>().lambda()
                .eq(Exhibitor::getExhibitionManageId, query.getExhibitionManageId())
                .eq(Exhibitor::getIsDeleted, BusinessConstant.NO)
                .eq(Exhibitor::getIsEnabled, BusinessConstant.YES)
        ), ExhibitorVO.class);
    }

    @Override
    public ExhibitorVO getExhibitorVO(Long id) {
        log.info("getExhibitorVO - 获取展商详情, id={}", id);
        Exhibitor exhibitor = getById(id);
        if (exhibitor == null) {
            return null;
        }
        ExhibitorVO exhibitorVO = BeanUtil.toBean(exhibitor, ExhibitorVO.class);
        // 查询负责展商的主场
        List<String> spaceCodeList = new ArrayList<>();
        spaceCodeList.add(exhibitor.getSpaceCode());
        Map<String, List<ServiceProviderVO>> serviceProviderMap = builderServiceProviderService.getServiceProviderVOMapByExhibitionId(exhibitor.getExhibitionManageId(), spaceCodeList, ServiceProviderTypeEnum.HOME_SERVICE_PROVIDER.getCode());
        setHome(exhibitorVO, serviceProviderMap);
        return exhibitorVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExhibitor(ExhibitorDTO exhibitorDTO) {
        log.info("saveExhibitor - 保存展商, exhibitorDTO={}", exhibitorDTO);
        // 校验展厅，必须保证展商系统的展厅与本系统展厅一致
        if (StrUtil.isBlank(exhibitorDTO.getSpaceName())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_SPACE_NOT_NULL.getCode(), "展商的展厅不可为空");
        }
        // spaceCode为空，说明展厅在本系统不存在
        if (StrUtil.isBlank(exhibitorDTO.getSpaceCode())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_SPACE_NOT_EXIST_IN_SYSTEM.getCode(), "展商的展厅在系统中不存在");
        }
        // 展位唯一性校验
        boolean isSiteUnique = checkSiteUnique(exhibitorDTO.getExternalExhibitorId(), exhibitorDTO.getSpaceCode(), exhibitorDTO.getSiteCode());
        if (!isSiteUnique) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_SITE_HAS_BIND.getCode(), "展位已被绑定，请更换展位");
        }
        // 保存展商
        Exhibitor exhibitor = BeanUtil.toBean(exhibitorDTO, Exhibitor.class);
        save(exhibitor);
        // 保存展会展商企业关系
        builderExhibitionCompanyService.saveByExhibitor(exhibitor);
        // 保存展会搭建商企业关系
        ServiceProviderVO builderServiceProvider = builderServiceProviderService.getById(exhibitor.getBuilderId());
        if (builderServiceProvider == null) {
            throw BizException.wrap(-1, "搭建商不存在");
        }
        builderExhibitionCompanyService.saveByBuilder(builderServiceProvider, exhibitor);
        // 保存展会搭建商关系
        ExhibitionServiceProviderDTO exhibitionServiceProviderDTO = new ExhibitionServiceProviderDTO();
        exhibitionServiceProviderDTO.setExhibitionManageId(exhibitorDTO.getExhibitionManageId());
        exhibitionServiceProviderDTO.setServiceProviderId(exhibitorDTO.getBuilderId());
        exhibitionServiceProviderDTO.setServiceProviderName(exhibitor.getBuilderName());
        exhibitionServiceProviderDTO.setServiceProviderType(ServiceProviderTypeEnum.BUILD_SERVICE_PROVIDER.getCode());
        return builderExhibitionServiceProviderService.saveExhibitionServiceProvider(exhibitionServiceProviderDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatch(List<ExhibitorDTO> list) {
        log.info("saveBatch - 批量保存展商, list={}", list);
        if (list == null || list.isEmpty()) {
            return false;
        }
        for (ExhibitorDTO exhibitorDTO : list) {
            saveExhibitor(exhibitorDTO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateExhibitor(ExhibitorDTO exhibitorDTO) {
        log.info("updateExhibitor - 修改展商, exhibitorDTO={}", exhibitorDTO);
        // 更新展位单双层或吊点
        updateIsDoubleAndIsPoint(exhibitorDTO);
        // 更新展商展位其他信息
        Exhibitor exhibitor = BeanUtil.toBean(exhibitorDTO, Exhibitor.class);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateIsDoubleAndIsPoint(ExhibitorDTO exhibitorDTO) {
        log.info("updateIsDoubleAndIsPoint - 更新展位单双层，是否吊点, exhibitorDTO={}", exhibitorDTO);
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        // 无需更新
        if (exhibitor.getIsDouble().equals(exhibitorDTO.getIsDouble()) && exhibitor.getIsPoint().equals(exhibitorDTO.getIsPoint())) {
            return false;
        }
        if (Objects.isNull(exhibitorDTO.getIsDouble()) && Objects.isNull(exhibitorDTO.getIsPoint())) {
            return false;
        }
        // 标摊不可编辑单双层与是否吊点
        if (ExhibitorSiteTypeEnum.STANDARD.eq(exhibitor.getSiteType())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_STANDARD_SITE_CAN_NOT_UPDATE);
        }
        ReportSpace reportSpace = reportSpaceService.getByExhibitorId(exhibitorDTO.getId());
        if (reportSpace != null
                && (ReportSpaceReportSpaceStatusEnum.SUBMIT.eq(reportSpace.getReportSpaceStatus())
                || ReportSpaceReportSpaceStatusEnum.APPROVED.eq(reportSpace.getReportSpaceStatus()))) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_SITE_CAN_NOT_UPDATE.getCode(), "展位已申请报馆未重置, 不可编辑单双层或吊点");
        }
        exhibitor.setIsDouble(exhibitorDTO.getIsDouble());
        exhibitor.setIsPoint(exhibitorDTO.getIsPoint());
        exhibitor.setIsReset(BusinessConstant.NO);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSiteStatus(ExhibitorDTO exhibitorDTO) {
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        ExhibitorSiteStatusEnum exhibitorSiteStatusEnum = ExhibitorSiteStatusEnum.get(exhibitorDTO.getSiteStatus());
        if (exhibitorSiteStatusEnum == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位状态不存在");
        }
        exhibitor.setSiteStatus(exhibitorSiteStatusEnum);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSiteStatusReporting(Long id) {
        log.info("updateSiteStatusReporting - 更新展位状态为报馆中, id={}", id);
        Exhibitor exhibitor = getById(id);
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        // 标摊无需报馆
        if (ExhibitorSiteTypeEnum.STANDARD.eq(exhibitor.getSiteType())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_STANDARD_NOT_NEED_REPORT_SPACE);
        }
        if (!ExhibitorSiteStatusEnum.UNREPORT.eq(exhibitor.getSiteStatus())) {
            return false;
        }
        exhibitor.setSiteStatus(ExhibitorSiteStatusEnum.REPORTING);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSiteStatusHasReported(Long id) {
        log.info("updateSiteStatusHasReported - 更新展位状态为已报馆, id={}", id);
        Exhibitor exhibitor = getById(id);
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        // 标摊无需报馆
        if (ExhibitorSiteTypeEnum.STANDARD.eq(exhibitor.getSiteType())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_STANDARD_NOT_NEED_REPORT_SPACE);
        }
        if (!ExhibitorSiteStatusEnum.UNREPORT.eq(exhibitor.getSiteStatus()) && !ExhibitorSiteStatusEnum.REPORTING.eq(exhibitor.getSiteStatus())) {
            return false;
        }
        exhibitor.setSiteStatus(ExhibitorSiteStatusEnum.REPORTED);
        // 更新展位进度
        exhibitor.setProcess(ExhibitorProcessEnum.IS_EARNEST_MONEY_SET);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateIsReset(Long id) {
        log.info("updateIsReset - 更新展位重置, id={}", id);
        Exhibitor exhibitor = getById(id);
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        // 校验服务订单，保证金订单，管理费订单先取消并退款
        checkForExhibitorReset(exhibitor);
        // 删除报馆信息
        reportSpaceService.removeByExhibitorId(id);
        // 更新展位重置状态为已重置
        exhibitor.setIsReset(BusinessConstant.YES);
        if (ExhibitorSiteTypeEnum.SPECIAL.eq(exhibitor.getSiteType())) {
            exhibitor.setSiteStatus(ExhibitorSiteStatusEnum.UNREPORT);
        }
        updateById(exhibitor);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateShouldEarnestMoney(ExhibitorDTO exhibitorDTO) {
        log.info("updateShouldEarnestMoney - 更新展商应付金额，exhibitorDTO={}", exhibitorDTO);
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST);
        }
        exhibitor.setIsEarnestMoneySet(BusinessConstant.YES);
        exhibitor.setShouldEarnestMoney(exhibitorDTO.getShouldEarnestMoney());
        if (Objects.nonNull(exhibitorDTO.getProcess())) {
            exhibitor.setProcess(exhibitorDTO.getProcess());
        }
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateShouldEarnestMoney(Long exhibitorId, BigDecimal shouldEarnestMoney) {
        ExhibitorDTO exhibitorDTO = new ExhibitorDTO();
        exhibitorDTO.setId(exhibitorId);
        exhibitorDTO.setShouldEarnestMoney(shouldEarnestMoney);
        return updateShouldEarnestMoney(exhibitorDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEarnestMoneyPayStatus(ExhibitorDTO exhibitorDTO) {
        log.info("updateEarnestMoneyPayStatus - 更新保证金支付状态, exhibitorDTO={}", exhibitorDTO);
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        exhibitor.setEarnestMoneyPayStatus(exhibitorDTO.getEarnestMoneyPayStatus());
        exhibitor.setActualEarnestMoney(exhibitorDTO.getActualEarnestMoney());
        if (ExhibitorEarnestMoneyPayStatusEnum.HAS_PAY.eq(exhibitorDTO.getEarnestMoneyPayStatus())) {
            // 计算保证金余额
            BigDecimal remainEarnestMoney = exhibitor.getRemainEarnestMoney();
            remainEarnestMoney = remainEarnestMoney.add(exhibitorDTO.getActualEarnestMoney());
            exhibitor.setRemainEarnestMoney(remainEarnestMoney);
            // 修改展位进度
            exhibitor.setProcess(ExhibitorProcessEnum.IS_EARNEST_MONEY_SET);
        }
        exhibitor.setEarnestMoneyPayTime(LocalDateTime.now());
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRemainEarnestMoney(ExhibitorDTO exhibitorDTO) {
        log.info("updateRemainEarnestMoney - 更新保证金余额, exhibitorDTO={}", exhibitorDTO);
        if (exhibitorDTO.getDeductedEarnestMoney() != null) {
            deductEarnestMoney(exhibitorDTO);
        }
        if (exhibitorDTO.getRefundEarnestMoney() != null) {
            refundEarnestMoney(exhibitorDTO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deductEarnestMoney(ExhibitorDTO exhibitorDTO) {
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        if (ExhibitorEarnestMoneyPayStatusEnum.NOT_PAY.eq(exhibitor.getEarnestMoneyPayStatus())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_EARNEST_MONEY_NOT_PAY.getCode(), "保证金未缴纳，无法扣除");
        }
        // 保证金剩余金额
        BigDecimal remainEarnestMoney = exhibitor.getRemainEarnestMoney();
        // 待扣除金额
        BigDecimal deductedEarnestMoney = exhibitorDTO.getDeductedEarnestMoney();
        if (remainEarnestMoney.compareTo(deductedEarnestMoney) < 0) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_REMAIN_EARNEST_MONEY_NOT_ENOUGH.getCode(), "保证金剩余金额不足扣除");
        }
        remainEarnestMoney = remainEarnestMoney.subtract(deductedEarnestMoney);
        exhibitor.setRemainEarnestMoney(remainEarnestMoney);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean refundEarnestMoney(ExhibitorDTO exhibitorDTO) {
        Exhibitor exhibitor = getById(exhibitorDTO.getId());
        if (exhibitor == null) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_NOT_EXIST.getCode(), "展位不存在");
        }
        if (ExhibitorEarnestMoneyPayStatusEnum.NOT_PAY.eq(exhibitor.getEarnestMoneyPayStatus())) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_EARNEST_MONEY_NOT_PAY.getCode(), "保证金未缴纳，无法退回");
        }
        // 保证金剩余金额
        BigDecimal remainEarnestMoney = exhibitor.getRemainEarnestMoney();
        // 待退还金额
        BigDecimal refundEarnestMoney = exhibitorDTO.getRefundEarnestMoney();
        remainEarnestMoney = remainEarnestMoney.add(refundEarnestMoney);
        exhibitor.setRemainEarnestMoney(remainEarnestMoney);
        return updateById(exhibitor);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByIds(List<Long> ids) {
        log.info("removeByIds - 批量移除展商, ids={}", ids);
        List<Exhibitor> list = listByIds(ids);
        if (list == null || list.isEmpty()) {
            return true;
        }
        // 校验是否可解绑
        for (Exhibitor exhibitor : list) {
            checkForExhibitorReset(exhibitor);
        }
        // 移除报馆信息
        reportSpaceService.removeByExhibitorIdList(ids);
        // 移除展会搭建商关系
        removeByIdsOfLogic(list);
        for (Exhibitor exhibitor : list) {
            // 展会ID，搭建商ID查询展商列表
            ExhibitorDTO query = new ExhibitorDTO();
            query.setExhibitionManageId(exhibitor.getExhibitionManageId());
            query.setBuilderId(exhibitor.getBuilderId());
            List<Exhibitor> existExhibitorList = listExhibitors(query);
            // 说明该搭建商在该展会还存在绑定的展商，则不能删除展会搭建商关系
            if (existExhibitorList != null && !existExhibitorList.isEmpty()) {
                continue;
            }
            ExhibitionServiceProviderDTO param = new ExhibitionServiceProviderDTO();
            param.setExhibitionManageId(exhibitor.getExhibitionManageId());
            param.setServiceProviderId(exhibitor.getBuilderId());
            param.setServiceProviderType(ServiceProviderTypeEnum.BUILD_SERVICE_PROVIDER.getCode());
            builderExhibitionServiceProviderService.deleteByServiceProviderId(param);
        }
        return true;
    }

    @Override
    public boolean checkSiteUnique(Long exhibitionId, Long builderId, String externalExhibitorId, String spaceCode, String siteCode) {
        ExhibitorDTO exhibitorDTO = new ExhibitorDTO();
        exhibitorDTO.setExhibitionManageId(exhibitionId);
        exhibitorDTO.setBuilderId(builderId);
        exhibitorDTO.setExternalExhibitorId(externalExhibitorId);
        exhibitorDTO.setSpaceCode(spaceCode);
        exhibitorDTO.setSiteCode(siteCode);
        List<Exhibitor> list = listExhibitors(exhibitorDTO);
        return list == null || list.isEmpty();
    }

    @Override
    public boolean checkSiteUnique(String externalExhibitorId, String spaceCode, String siteCode) {
        if (StrUtil.isBlank(externalExhibitorId)) {
            throw BizException.wrap(-1, "展商系统展商ID不可为空");
        }
        if (StrUtil.isBlank(spaceCode)) {
            throw BizException.wrap(-1, "展商展厅不可为空");
        }
        if (StrUtil.isBlank(siteCode)) {
            throw BizException.wrap(-1, "展商展位不可为空");
        }
        ExhibitorDTO query = new ExhibitorDTO();
        query.setExternalExhibitorId(externalExhibitorId);
        query.setSpaceCode(spaceCode);
        query.setSiteCode(siteCode);
        List<Exhibitor> list = listExhibitors(query);
        return list == null || list.isEmpty();
    }

    @Override
    public boolean checkInviteCodeExist(String inviteCode) {
        List<Exhibitor> list = listByInviteCode(inviteCode);
        return list != null && !list.isEmpty();
    }

    @Override
    public List<String> checkOrderForExhibitorReset(List<ServiceOrderVO> serviceOrderList) {
        if (serviceOrderList == null || serviceOrderList.isEmpty()) {
            // 没有订单，可以重置
            return Collections.emptyList();
        }
        boolean isServiceOrderDispatch = false;
        boolean isServiceOrderReportVenue = false;
        boolean isServiceOrderSubmit = false;
        boolean isManageOrderSubmit = false;
        for (ServiceOrderVO serviceOrderVO : serviceOrderList) {
            if (serviceOrderVO.getIsManageExpense() == BusinessConstant.NO) {
                if (ServiceOrderOrderStatusEnum.CANCEL.eq(serviceOrderVO.getOrderStatus())) {
                    continue;
                }
                // 服务订单已经派单，则需要先处理已派单的订单，包含主场服务和场馆服务
                if (ServiceOrderWorkOrderStatusEnum.PARTIAL_DISPATCH.eq(serviceOrderVO.getWorkOrderStatus())
                        || ServiceOrderWorkOrderStatusEnum.HAS_DISPATCH.eq(serviceOrderVO.getWorkOrderStatus())
                        || ServiceOrderWorkOrderStatusEnum.HAS_RECEIVE.eq(serviceOrderVO.getWorkOrderStatus())
                        || ServiceOrderWorkOrderStatusEnum.PARTIAL_COMPLETE.eq(serviceOrderVO.getWorkOrderStatus())
                        || ServiceOrderWorkOrderStatusEnum.COMPLETE.eq(serviceOrderVO.getWorkOrderStatus())
                        || ServiceOrderWorkOrderStatusEnum.REVOKE.eq(serviceOrderVO.getWorkOrderStatus())) {
                    isServiceOrderDispatch = true;
                }
                // 服务订单已经报馆，需要先处理
                if (ServiceOrderOrderStatusEnum.PARTIAL_REPORT_VENUE.eq(serviceOrderVO.getOrderStatus())
                        || ServiceOrderOrderStatusEnum.HAS_REPORT_VENUE.eq(serviceOrderVO.getOrderStatus())) {
                    isServiceOrderReportVenue = true;
                }
                // 服务订单已提交，需要先取消订单
                if (ServiceOrderOrderStatusEnum.SUBMIT.eq(serviceOrderVO.getOrderStatus())) {
                    isServiceOrderSubmit = true;
                }
            }
        }
        for (ServiceOrderVO serviceOrderVO : serviceOrderList) {
            if (serviceOrderVO.getIsManageExpense() == BusinessConstant.YES) {
                // 管理费订单已提交，需要先取消订单
                if (ServiceOrderOrderStatusEnum.SUBMIT.eq(serviceOrderVO.getOrderStatus())) {
                    isManageOrderSubmit = true;
                }
            }
        }
        List<String> errorCodeList = new ArrayList<>();
        // 服务订单已经派单，则需要先处理已派单的订单，包含主场服务和场馆服务
        if (isServiceOrderDispatch) {
            errorCodeList.add("1001");
        }
        // 展位的服务订单已经报馆
        if (isServiceOrderReportVenue) {
            errorCodeList.add("1002");
        }
        // 展位有服务订单，请先取消订单
        if (isServiceOrderSubmit) {
            errorCodeList.add("1003");
        }
        if (isManageOrderSubmit) {
            // 展位有管理费订单，请先取消订单
            errorCodeList.add("1004");
        }
        return errorCodeList;
    }

    @Override
    public List<String> checkBondForExhibitorReset(List<BondManageVO> bondManageList) {
        if (bondManageList == null || bondManageList.isEmpty()) {
            // 没有保证金订单，可以重置
            return Collections.emptyList();
        }
        boolean isBondSubmit = false;
        for (BondManageVO bondManageVO : bondManageList) {
            // 保证金订单已提交，需要先取消订单
            if (BondManageOrderStatusEnum.SUBMIT.eq(bondManageVO.getOrderStatus())) {
                isBondSubmit = true;
            }
        }
        // 展位有保证金订单，请先取消订单
        List<String> errorCodeList = new ArrayList<>();
        if (isBondSubmit) {
            errorCodeList.add("1005");
        }
        return errorCodeList;
    }

    @Override
    public List<String> checkBuilderRepairReportForExhibitorReset(List<BuilderRepairReportVO> builderRepairReportList) {
        if (builderRepairReportList == null || builderRepairReportList.isEmpty()) {
            return Collections.emptyList();
        }
        boolean hasBuilderRepairReport = false;
        for (BuilderRepairReportVO builderRepairReportVO: builderRepairReportList) {
            if (BuilderRepairReportRepairStatusEnum.CANCEL.eq(builderRepairReportVO.getRepairStatus())) {
                continue;
            }
            hasBuilderRepairReport = true;
        }
        List<String> errorCodeList = new ArrayList<>();
        if (hasBuilderRepairReport) {
            errorCodeList.add("1007");
        }
        return errorCodeList;
    }

    @Override
    public List<String> checkWorkOvertimeForExhibitorReset(List<WorkOvertimeVO> workOvertimeList) {
        if (workOvertimeList == null || workOvertimeList.isEmpty()) {
            return Collections.emptyList();
        }
        List<String> errorCodeList = new ArrayList<>();
        errorCodeList.add("1008");
        return errorCodeList;
    }

    @Override
    public boolean checkForExhibitorReset(Exhibitor exhibitor) {
        List<String> errorCodeList = new ArrayList<>();
        // 查询展位下的加班申请
        List<WorkOvertimeVO> workOvertimeList = builderWorkOvertimeService.queryByExhibitor(exhibitor.getExhibitionManageId(), exhibitor.getBuilderId(), exhibitor.getSpaceCode(), exhibitor.getSiteName());
        // 加班申请是否满足展位重置条件
        List<String> workOvertimeErrorCode = checkWorkOvertimeForExhibitorReset(workOvertimeList);
        if (workOvertimeErrorCode != null && !workOvertimeErrorCode.isEmpty()) {
            throw BizException.wrap(1008, "展位存在加班申请，无法处理");
        }
        // 查询展位下的报修申请
        List<BuilderRepairReportVO> builderRepairReportList = builderBuilderRepairReportService.queryByExhibitor(exhibitor.getExhibitionManageId(), exhibitor.getBuilderId(), exhibitor.getSpaceCode(), exhibitor.getSiteName());
        // 报修申请是否满足展位重置条件
        List<String> repairErrorCode = checkBuilderRepairReportForExhibitorReset(builderRepairReportList);
        if (repairErrorCode != null && !repairErrorCode.isEmpty()) {
            throw BizException.wrap(1007, "展位存在报修申请，无法处理");
        }
        // 查询展位下的服务订单
        List<ServiceOrderVO> serviceOrderList = builderHomeServiceOrderService.queryOrderByExhibitorId(exhibitor.getId());
        // 服务订单是否满足展位重置条件
        List<String> orderErrorMsg = checkOrderForExhibitorReset(serviceOrderList);
        // 查询展位下的保证金订单
        List<Long> exhibitorIdList = new ArrayList<>();
        exhibitorIdList.add(exhibitor.getId());
        List<BondManageVO> bondManageList = builderHomeBondManageService.queryByExhibitorIdList(exhibitorIdList);
        // 保证金订单是否满足展位重置条件
        List<String> bondErrorMsg = checkBondForExhibitorReset(bondManageList);

        errorCodeList.addAll(orderErrorMsg);
        errorCodeList.addAll(bondErrorMsg);
        if (!errorCodeList.isEmpty()) {
            throw BizException.wrap(BuilderExceptionCode.EXHIBITOR_RESET_VALID_FAILURE.getCode(), CollectionUtil.join(errorCodeList, ","));
        }
        return true;
    }

    private QueryWrapper<Exhibitor> createExhibitorQueryWrapper(ExhibitorDTO query) {
        QueryWrapper<Exhibitor> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(Exhibitor::getIsDeleted, BusinessConstant.DELETE_NO)
                .like(StrUtil.isNotBlank(query.getExhibitorName()), Exhibitor::getExhibitorName, query.getExhibitorName())
                .like(StrUtil.isNotBlank(query.getSiteName()), Exhibitor::getSiteName, query.getSiteName())
                .eq(query.getSiteType() != null, Exhibitor::getSiteType, query.getSiteType())
                .like(StrUtil.isNotBlank(query.getSpaceName()), Exhibitor::getSpaceName, query.getSpaceName())
                .like(StrUtil.isNotBlank(query.getContactMobile()), Exhibitor::getContactMobile, query.getContactMobile())
                .like(StrUtil.isNotBlank(query.getExhibitorContactsTel()), Exhibitor::getExhibitorContactsTel, query.getExhibitorContactsTel())
                .eq(query.getBuilderId() != null, Exhibitor::getBuilderId, query.getBuilderId())
                .eq(query.getExhibitionManageId() != null, Exhibitor::getExhibitionManageId, query.getExhibitionManageId())
                .eq(StrUtil.isNotBlank(query.getSpaceCode()), Exhibitor::getSpaceCode, query.getSpaceCode())
                .eq(StrUtil.isNotBlank(query.getSiteCode()), Exhibitor::getSiteCode, query.getSiteCode())
                .eq(StrUtil.isNotBlank(query.getExternalExhibitorId()), Exhibitor::getExternalExhibitorId, query.getExternalExhibitorId())
                .eq(StrUtil.isNotBlank(query.getSiteStatus()), Exhibitor::getSiteStatus, query.getSiteStatus())
                .eq(query.getId() != null, Exhibitor::getId, query.getId())
                .in(query.getSpaceCodeList() != null && !query.getSpaceCodeList().isEmpty(), Exhibitor::getSpaceCode, query.getSpaceCodeList())
                .eq(StrUtil.isNotBlank(query.getInviteCode()), Exhibitor::getInviteCode, query.getInviteCode())
                .and(Objects.nonNull(query.getPerfectMatch()) && query.getPerfectMatch(), e -> e.eq(StrUtil.isNotBlank(query.getExhibitorName()), Exhibitor::getExhibitorName, query.getExhibitorName())
                        .eq(StrUtil.isNotBlank(query.getSiteName()), Exhibitor::getSiteName, query.getSiteName())
                        .eq(StrUtil.isNotBlank(query.getSpaceName()), Exhibitor::getSpaceName, query.getSpaceName()))
        ;
        return queryWrapper;
    }

    private QueryWrapper<Exhibitor> createQueryWrapperForServiceProviderSite(ExhibitorDTO model) {
        QueryWrapper<Exhibitor> wrapper = new QueryWrapper<>();
        wrapper.eq("e.is_deleted", BusinessConstant.NO)
                .eq("e.is_enabled", BusinessConstant.YES)
                .eq(model.getExhibitionManageId() != null, "e.exhibition_manage_id", model.getExhibitionManageId())
                .eq(model.getBuilderId() != null, "e.builder_id", model.getBuilderId())
                .eq(Objects.nonNull(model.getSiteType()), "e.site_type", model.getSiteType())
                .eq(model.getProcess() != null, "e.process", model.getProcess())
                .eq(StrUtil.isNotBlank(model.getSiteStatus()), "e.site_status", model.getSiteStatus())
                .eq(StrUtil.isNotBlank(model.getSpaceCode()), "e.space_code", model.getSpaceCode())
                .eq(StrUtil.isNotBlank(model.getExhibitorName()), "e.exhibitor_name", model.getExhibitorName())
                .in(model.getSpaceCodeList() != null && !model.getSpaceCodeList().isEmpty(), "e.space_code", model.getSpaceCodeList())
                .like(StrUtil.isNotBlank(model.getSpaceName()), "e.space_name", model.getSpaceName())
                .like(StrUtil.isNotBlank(model.getSiteName()), "e.site_name", model.getSiteName())
                .like(StrUtil.isNotBlank(model.getBuilderName()), "e.builder_name", model.getBuilderName())
                .like(StrUtil.isNotBlank(model.getConstructionPrincipal()), "rb.construction_principal", model.getConstructionPrincipal())
                .like(StrUtil.isNotBlank(model.getPrincipalPhone()), "rb.principal_phone", model.getPrincipalPhone())
                .eq(Objects.nonNull(model.getIsBuilder()), "rs.report_space_status", ReportVenueSpaceAuditReportSpaceStatusEnum.APPROVED.getCode())
                .eq(StrUtil.isNotBlank(model.getReportSpaceStatus()), "rs.report_space_status", model.getReportSpaceStatus())
                .and(StrUtil.isNotBlank(model.getKeyword()), keywordQueryWrapper -> keywordQueryWrapper
                        .like("e.site_name", model.getKeyword())
                        .or()
                        .like("e.exhibitor_name", model.getKeyword())
                        .or()
                        .like("e.exhibitor_contacts", model.getKeyword())
                        .or()
                        .like("e.exhibitor_contacts_tel", model.getKeyword())
                        .or()
                        .like("e.builder_name", model.getKeyword())
                        .or()
                        .like("e.contact", model.getKeyword())
                        .or()
                        .like("e.contact_mobile", model.getKeyword()))
                .and(StrUtil.isNotBlank(model.getHomeCheckKeyword()), homeCheckKeywordQueryWrapper -> homeCheckKeywordQueryWrapper
                        .like("e.space_name", model.getHomeCheckKeyword())
                        .or()
                        .like("e.site_name", model.getHomeCheckKeyword())
                        .or()
                        .like("e.exhibitor_name", model.getHomeCheckKeyword())
                        .or()
                        .like("e.builder_name", model.getHomeCheckKeyword()))
        ;
        return wrapper;
    }

    private List<ExhibitorVO> toExhibitorList(List<ActorInfo> actorInfoList) {
        List<ExhibitorVO> exhibitorList = new ArrayList<>();
        for (ActorInfo actorInfo : actorInfoList) {
            List<ActorInfoBoot> boothList = actorInfo.getBoothList();
            List<ActorPersonJoin> personJoinList = actorInfo.getPersonJoinList();
            if (boothList == null || boothList.isEmpty()) {
                continue;
            }
            for (int i = 0; i < boothList.size(); i++) {
                ActorInfoBoot boot = boothList.get(i);
                ExhibitorVO exhibitorVO = new ExhibitorVO();
                // 外部系统展商ID
                exhibitorVO.setExternalExhibitorId(actorInfo.getAtrID() + "");
                // 展商名称
                exhibitorVO.setExhibitorName(actorInfo.getAtrName());
                // 展厅号
                String srmName = boot.getSrmName();
                if (StrUtil.isNotBlank(srmName)) {
                    R<SpaceVO> spaceResult = spaceFeign.getBySpaceName(srmName);
                    if (spaceResult.getIsSuccess()) {
                        SpaceVO spaceVO = spaceResult.getData();
                        if (spaceVO != null) {
                            exhibitorVO.setSpaceCode(spaceVO.getSpaceCode());
                        }
                    }
                    exhibitorVO.setSpaceName(boot.getSrmName());
                }
                // 展位id
                exhibitorVO.setSiteCode(boot.getBthID() + "");
                // 展位号
                exhibitorVO.setSiteName(boot.getBthCode());
                // 展位类型
                String bthBigType = boot.getBthBigType();
                if (StrUtil.isNotBlank(bthBigType)) {
                    if ("RS".equals(bthBigType)) {
                        exhibitorVO.setSiteType(ExhibitorSiteTypeEnum.SPECIAL);
                    } else if ("SS".equals(bthBigType)) {
                        exhibitorVO.setSiteType(ExhibitorSiteTypeEnum.STANDARD);
                    }
                }
                // 展位面积
                Long bthArea = boot.getBthArea();
                if (bthArea != null) {
                    BigDecimal siteArea = BigDecimal.valueOf(bthArea);
                    exhibitorVO.setSiteArea(siteArea);
                }
                // 联系人
                if (personJoinList != null && !personJoinList.isEmpty()) {
                    ActorPersonJoin personJoin;
                    if (boothList.size() == personJoinList.size()) {
                        personJoin = personJoinList.get(i);
                    } else {
                        personJoin = personJoinList.get(0);
                    }
                    exhibitorVO.setExhibitorContacts(personJoin.getPsjName());
                    exhibitorVO.setExhibitorContactsTel(personJoin.getPsjMobile());
                }
                exhibitorList.add(exhibitorVO);
            }
        }
        return exhibitorList;
    }

    /**
     * 注入报馆状态
     *
     * @param exhibitorVO          the exhibitor vo
     * @param reportSpaceStatusMap the report space status map
     */
    private void setReportSpaceStatus(ExhibitorVO exhibitorVO, Map<Long, ReportSpace> reportSpaceStatusMap) {
        // 添加展位报馆状态
        ReportSpace reportSpace = reportSpaceStatusMap.get(exhibitorVO.getId());
        if (reportSpace != null) {
            exhibitorVO.setReportSpaceStatus(reportSpace.getReportSpaceStatus().getCode());
        }
    }

    /**
     * 注入主场状态
     *
     * @param exhibitorVO        the exhibitor vo
     * @param serviceProviderMap the service provider map
     */
    private void setHome(ExhibitorVO exhibitorVO, Map<String, List<ServiceProviderVO>> serviceProviderMap) {
        // 添加负责的主场
        List<ServiceProviderVO> serviceProviderList = serviceProviderMap.get(exhibitorVO.getSpaceCode());
        if (serviceProviderList != null && !serviceProviderList.isEmpty()) {
            ServiceProviderVO homeServiceProvider = serviceProviderList.get(0);
            exhibitorVO.setHomeId(homeServiceProvider.getId());
            exhibitorVO.setHomeName(homeServiceProvider.getCompanyName());
        }
    }

    /**
     * 注入管理费缴纳状态
     *
     * @param exhibitorVO             the exhibitor vo
     * @param manageOrderPayStatusMap the manage order pay status map
     */
    private void setManagePayStatus(ExhibitorVO exhibitorVO, Map<Long, String> manageOrderPayStatusMap) {
        // 管理费缴纳状态
        String manageOrderPayStatus = manageOrderPayStatusMap.get(exhibitorVO.getId());
        exhibitorVO.setManageOrderPayStatus(manageOrderPayStatus);
    }

    /**
     * 注入保证金缴纳状态
     *
     * @param exhibitorVO      the exhibitor vo
     * @param bondPayStatusMap the bond pay status map
     */
    private void setBondPayStatus(ExhibitorVO exhibitorVO, Map<Long, String> bondPayStatusMap) {
        // 保证金缴纳状态
        String bondPayStatus = bondPayStatusMap.get(exhibitorVO.getId());
        exhibitorVO.setBondPayStatus(bondPayStatus);
    }

    private void decryptContactMobile(ExhibitorVO exhibitorVO) {
        String contactMobile = exhibitorVO.getContactMobile();
        if (StrUtil.isNotBlank(contactMobile)) {
            String decryptContractMobile = TypeHandlerUtil.decrypt(contactMobile);
            exhibitorVO.setContactMobile(decryptContractMobile);
        }
    }

    private void decryptExhibitorContactsTel(ExhibitorVO exhibitorVO) {
        String exhibitorContactsTel = exhibitorVO.getExhibitorContactsTel();
        if (StrUtil.isNotBlank(exhibitorContactsTel)) {
            String decryptExhibitorContractTel = TypeHandlerUtil.decrypt(exhibitorContactsTel);
            exhibitorVO.setExhibitorContactsTel(decryptExhibitorContractTel);
        }
    }

    private void decryptPrincipalPhone(ExhibitorVO exhibitorVO) {
        String principalPhone = exhibitorVO.getPrincipalPhone();
        if (StrUtil.isNotBlank(principalPhone)) {
            String decryptPrincipalPhone = TypeHandlerUtil.decrypt(principalPhone);
            exhibitorVO.setPrincipalPhone(decryptPrincipalPhone);
        }
    }
}
